package com.chatTools.protocol;

import com.google.gson.*;

import java.io.*;
import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets;

/**
 * @author： pang-yun
 * @date： 2021-09-18 13:11
 * 功能目的 ：用于  扩展 序列化  反序列化算法
 */

public interface Serializer {
    /**
     * 反序列化算法   <T> 声明此方法为泛型方法  T 返回类型
     *
     * @param clazz 反序列化为何种类型
     * @param bytes
     * @param <T>
     * @return
     */
    <T> T deserializer(Class<T> clazz, byte[] bytes);


    // 序列化算法
    <T> byte[] serializer(T object);


    enum Algorithm implements Serializer {
        Java {
            @Override
            public <T> T deserializer(Class<T> clazz, byte[] bytes) {

                try {

                    ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
                    // 反序列化流
                    ObjectInputStream ois = new ObjectInputStream(bis);

                    return (T) ois.readObject();
                } catch (IOException | ClassNotFoundException e) {
                    throw new RuntimeException("反序列化失败！", e);
                }
            }

            @Override
            public <T> byte[] serializer(T object) {
                try {
                    ByteArrayOutputStream bos = new ByteArrayOutputStream();
                    // 序列化流
                    ObjectOutputStream oos = new ObjectOutputStream(bos);
                    // 向序列化流写入
                    oos.writeObject(object);
                    // 反流字节流
                    return bos.toByteArray();
                } catch (IOException e) {
                    throw new RuntimeException("序列化失败......", e);
                }
            }
        },

        Json {
            //Gson是谷歌官方推出的支持 JSON &#45;&#45; Java Object 相互转换的 Java序列化/反序列化 库

            @Override
            public <T> T deserializer(Class<T> clazz, byte[] bytes) {
                Gson gson = new GsonBuilder().registerTypeAdapter(Class.class, new Serializer.ClassCodec()).create();
                String json = new String(bytes, StandardCharsets.UTF_8);
                return gson.fromJson(json, clazz);
            }

            @Override
            public <T> byte[] serializer(T object) {
                Gson gson = new GsonBuilder().registerTypeAdapter(Class.class, new Serializer.ClassCodec()).create();
                // 使用Google 的 gson 将代码强制使用 utf-8
                String json = gson.toJson(object);
                return json.getBytes(StandardCharsets.UTF_8);
            }
        }


    }

    class ClassCodec implements JsonSerializer<Class<?>>, JsonDeserializer<Class<?>> {
        @Override
        public Class<?> deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
            try {
                String string = jsonElement.getAsString();
                return Class.forName(string);
            } catch (ClassNotFoundException e) {

                throw new JsonParseException(e);
            }
        }

        @Override
        public JsonElement serialize(Class<?> aClass, Type type, JsonSerializationContext jsonSerializationContext) {
            // class --> json
            return new JsonPrimitive(aClass.getName());
        }
    }

}
